﻿using System;
using System.Collections.Generic;
using UniRx;
using UnityEngine;
using UnityEngine.Events;

/// <summary>
/// 命令管理类。用于对命令进行注册、调用和实现
/// </summary>
public class CommandManager
{
    private static Dictionary<string, IObservable<Unit>> s_Streams = new Dictionary<string, IObservable<Unit>>();
    private static Dictionary<string, UnityAction> s_Commonds = new Dictionary<string, UnityAction>();

    /// <summary>
    /// 注册命令发射流，在命令发射处调用此方法
    /// </summary>
    public static void RegisterStream(string commond, IObservable<Unit> stream, bool isCover = false)
    {
        if (commond.IsEmpty())
        {
            Debug.LogWarning($"CommondManager 命令发射流注册失败：命令为空 {commond}");
            return;
        }
        if (isCover)
        {
            s_Streams[commond] = stream;
        }
        else
        {
            if (!s_Streams.ContainsKey(commond))
            {
                s_Streams.Add(commond, stream);
            }
            else
            {
                s_Streams[commond] = s_Streams[commond].Merge(stream);
            }
        }
        Debug.Log($"CommondManager 命令注册成功： {commond}");
    }

    /// <summary>
    /// 删除命令发射流
    /// </summary>
    public static void DeleteStream(string commond)
    {
        if (commond.IsEmpty()) return;
        s_Streams.Remove(commond);
    }

    /// <summary>
    /// 查找命令流
    /// </summary>
    public static IObservable<Unit> FindStream(string commond)
    {
        if (!s_Streams.TryGetValue(commond, out var stream))
        {
            Debug.LogError($"CommondManager 命令发射流查找失败：找不到命令流 {commond}");
        }
        return stream;
    }

    /// <summary>
    /// 订阅命令，在命令需求处调用此方法
    /// </summary>
    public static void Subscribe(string commond, UnityAction action)
    {
        if (commond.IsEmpty())
        {
            Debug.LogWarning($"CommondManager 命令订阅失败：命令为空 {commond}");
            return;
        }
        if (!s_Streams.ContainsKey(commond))
        {
            Debug.LogWarning($"CommondManager 命令订阅失败：未找到 {commond} 的发射流");
            return;
        }
        if (!s_Commonds.ContainsKey(commond))
        {
            s_Commonds.Add(commond, action);
            s_Streams[commond].Subscribe(_ => action?.Invoke());
        }
        else
        {
            s_Commonds[commond] += action;
        }
        Debug.Log($"CommondManager 命令订阅成功： {commond}");
    }

    /// <summary>
    /// 取消订阅
    /// </summary>
    public static void Dispose(string commond, UnityAction action)
    {
        if (s_Commonds.ContainsKey(commond))
        {
            s_Commonds[commond] -= action;
            if (s_Commonds[commond] == null)
            {
                s_Commonds.Remove(commond);
            }
        }
    }

    /// <summary>
    /// 取消所有订阅
    /// </summary>
    public static void Dispose(string commond)
    {
        if (s_Commonds.ContainsKey(commond))
        {
            s_Commonds.Remove(commond);
        }
    }

    /// <summary>
    /// 查找所有命令订阅者
    /// </summary>
    private static UnityAction FindAction(string commond)
    {
        if (!s_Commonds.TryGetValue(commond, out var action))
        {
            Debug.LogError($"CommondManager 命令订阅者查找失败：找不到命令订阅者 {commond}");
        }
        return action;
    }

    /// <summary>
    /// 调用命令
    /// </summary>
    public static void Call(string commond)
    {
        var action = FindAction(commond);
        if (action != null)
        {
            Debug.Log($"CommondManager 命令调用失败：命令 {commond} 没有订阅者");
            return;
        }
        action.Invoke();
    }
}